package com.dmai.aiet.epc.archive.filter;

import com.dmai.aiet.epc.archive.properties.TraceProperties;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

@Slf4j
@Configuration
@ConditionalOnProperty(value = "app.trace.enable", havingValue = "true", matchIfMissing = true)
public class RequestLogFilter implements Filter {

    @Autowired
    private TraceProperties traceProperties;


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        String contentType = servletRequest.getContentType();
        if (servletRequest instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            String url = request.getRequestURI();
            String method = request.getMethod();

            if (contentType != null && contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE)) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else if (HttpMethod.POST.matches(method)) {
                RequestWrapper requestWrapper = new RequestWrapper(request);
                if (traceProperties.getRequestParam()) {
                    String body = new String(requestWrapper.getBody(), servletRequest.getCharacterEncoding());
                    log.info("request：method = {}，path = {}，param = {}", method, url, body);
                } else {
                    log.info("request：method = {}，path = {}", method, url);
                }
                filterChain.doFilter(requestWrapper, servletResponse);
            } else if (HttpMethod.GET.matches(method)) {
                if (traceProperties.getRequestParam()) {
                    String queryString = request.getQueryString();
                    log.info("request：method = {}，path = {}，param = {}", method, url, queryString);
                } else {
                    log.info("request：method = {}，path = {}", method, url);
                }
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                filterChain.doFilter(servletRequest, servletResponse);
            }

        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
}